#!/bin/bash

# LingShu构建脚本
# Copyright 2024 LingShu Team

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 项目信息
PROJECT_NAME="lingshu"
VERSION="0.1.0"
BUILD_DIR="target"
SRC_DIR="src"

# 打印带颜色的消息
print_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 显示帮助信息
show_help() {
    echo "LingShu构建脚本"
    echo ""
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  build       编译项目 (标准模式)"
    echo "  build-opt   编译项目 (优化模式，减小体积)"
    echo "  build-min   编译项目 (最小化模式，最小体积)"
    echo "  test        运行测试"
    echo "  clean       清理构建文件"
    echo "  install     安装依赖"
    echo "  run         运行服务器"
    echo "  example     运行示例"
    echo "  benchmark   运行性能测试"
    echo "  format      格式化代码"
    echo "  lint        代码检查"
    echo "  package     打包发布"
    echo "  status      显示项目状态"
    echo "  help        显示帮助信息"
    echo ""
    echo "示例:"
    echo "  $0 build           # 编译项目"
    echo "  $0 test            # 运行测试"
    echo "  $0 run             # 运行服务器"
    echo "  $0 example         # 运行示例"
}

# 检查仓颉编译器
check_cangjie() {
    if ! command -v cjpm &> /dev/null; then
        print_error "未找到仓颉包管理器 (cjpm)"
        print_info "请安装仓颉开发环境"
        exit 1
    fi
    
    print_info "仓颉版本: $(cjpm --version)"
}

# 创建构建目录
create_build_dir() {
    if [ ! -d "$BUILD_DIR" ]; then
        mkdir -p "$BUILD_DIR"
        print_info "创建构建目录: $BUILD_DIR"
    fi
}

# 安装依赖
install_deps() {
    print_info "安装项目依赖..."
    
    if [ -f "cjpm.toml" ]; then
        cjpm install
        print_success "依赖安装完成"
    else
        print_warning "未找到 cjpm.toml 文件"
    fi
}

# 编译项目
build_project() {
    print_info "开始编译 $PROJECT_NAME v$VERSION (标准模式)..."
    
    create_build_dir
    
    # 编译主程序
    print_info "编译主程序..."
    cjpm build
    
    if [ $? -eq 0 ]; then
        print_success "编译完成: $BUILD_DIR/$PROJECT_NAME"
        
        # 显示二进制文件信息
        if [ -f "$BUILD_DIR/$PROJECT_NAME" ]; then
            local size=$(du -h "$BUILD_DIR/$PROJECT_NAME" | cut -f1)
            print_info "二进制文件大小: $size"
        fi
    else
        print_error "编译失败"
        exit 1
    fi
}

# 优化编译（减小体积）
build_project_optimized() {
    print_info "开始编译 $PROJECT_NAME v$VERSION (优化模式)..."
    
    create_build_dir
    
    # 备份原始配置
    if [ -f "cjpm.toml" ]; then
        cp cjpm.toml cjpm.toml.backup
    fi
    
    # 使用优化配置
    if [ -f "cjpm_minimal.toml" ]; then
        cp cjpm_minimal.toml cjpm.toml
    fi
    
    # 编译主程序
    print_info "编译优化版本..."
    cjpm build
    
    # 恢复原始配置
    if [ -f "cjpm.toml.backup" ]; then
        mv cjpm.toml.backup cjpm.toml
    fi
    
    if [ $? -eq 0 ]; then
        print_success "优化编译完成: $BUILD_DIR/$PROJECT_NAME"
        
        # 显示二进制文件信息
        if [ -f "$BUILD_DIR/$PROJECT_NAME" ]; then
            local size=$(du -h "$BUILD_DIR/$PROJECT_NAME" | cut -f1)
            print_info "优化后二进制文件大小: $size"
        fi
    else
        print_error "优化编译失败"
        exit 1
    fi
}

# 最小化编译（最小体积）
build_project_minimal() {
    print_info "开始编译 $PROJECT_NAME v$VERSION (最小化模式)..."
    
    create_build_dir
    
    # 备份原始配置
    if [ -f "cjpm.toml" ]; then
        cp cjpm.toml cjpm.toml.backup
    fi
    
    # 使用最小化配置
    if [ -f "cjpm_minimal.toml" ]; then
        cp cjpm_minimal.toml cjpm.toml
        
        # 编译主程序
        print_info "编译最小化版本..."
        cjpm build
    else
        print_error "未找到最小化配置文件 cjpm_minimal.toml"
        exit 1
    fi
    
    # 恢复原始配置
    if [ -f "cjpm.toml.backup" ]; then
        mv cjpm.toml.backup cjpm.toml
    fi
    
    if [ $? -eq 0 ]; then
        print_success "最小化编译完成: $BUILD_DIR/$PROJECT_NAME"
        
        # 显示二进制文件信息
        if [ -f "$BUILD_DIR/$PROJECT_NAME" ]; then
            local size=$(du -h "$BUILD_DIR/$PROJECT_NAME" | cut -f1)
            print_info "最小化后二进制文件大小: $size"
        fi
    else
        print_error "最小化编译失败"
        exit 1
    fi
}

# 运行测试
run_tests() {
    print_info "运行测试套件..."
    
    # 编译测试
    print_info "编译测试..."
    cjpm test --compile
    
    # 运行单元测试
    print_info "运行单元测试..."
    cjpm test
    
    if [ $? -eq 0 ]; then
        print_success "所有测试通过"
    else
        print_error "测试失败"
        exit 1
    fi
}

# 清理构建文件
clean_build() {
    print_info "清理构建文件..."
    
    if [ -d "$BUILD_DIR" ]; then
        rm -rf "$BUILD_DIR"
        print_success "构建目录已清理"
    fi
    
    # 清理缓存文件
    if [ -d ".cjpm" ]; then
        rm -rf ".cjpm"
        print_success "缓存文件已清理"
    fi
}

# 运行服务器
run_server() {
    print_info "启动LingShu服务器..."
    
    if [ ! -f "$BUILD_DIR/$PROJECT_NAME" ]; then
        print_warning "未找到可执行文件，正在编译..."
        build_project
    fi
    
    # 检查配置文件
    if [ ! -f "config.toml" ]; then
        print_warning "未找到配置文件，使用默认配置"
    fi
    
    # 启动服务器
    "./$BUILD_DIR/$PROJECT_NAME" "$@"
}

# 运行示例
run_example() {
    print_info "运行发布订阅示例..."
    
    # 编译示例
    print_info "编译示例程序..."
    cjpm build --target examples/simple_pubsub.cj
    
    if [ $? -eq 0 ]; then
        print_success "示例编译完成"
        ./main
    else
        print_error "示例编译失败"
        exit 1
    fi
}

# 运行性能测试
run_benchmark() {
    print_info "运行性能测试..."
    
    # 编译性能测试
    print_info "编译性能测试..."
    cjpm build --target benchmarks/benchmark.cj --output "$BUILD_DIR/benchmark"
    
    if [ $? -eq 0 ]; then
        print_success "性能测试编译完成"
        "./$BUILD_DIR/benchmark"
    else
        print_error "性能测试编译失败"
        exit 1
    fi
}

# 格式化代码
format_code() {
    print_info "格式化代码..."
    
    # 查找所有.cj文件并格式化
    find "$SRC_DIR" -name "*.cj" -exec cjfmt {} \;
    find "tests" -name "*.cj" -exec cjfmt {} \; 2>/dev/null || true
    find "examples" -name "*.cj" -exec cjfmt {} \; 2>/dev/null || true
    
    print_success "代码格式化完成"
}

# 代码检查
lint_code() {
    print_info "运行代码检查..."
    
    # 运行代码检查工具
    cjpm lint
    
    if [ $? -eq 0 ]; then
        print_success "代码检查通过"
    else
        print_warning "代码检查发现问题"
    fi
}

# 打包发布
package_release() {
    print_info "打包发布版本..."
    
    # 确保项目已编译
    build_project
    
    # 创建发布目录
    local release_dir="$BUILD_DIR/release"
    mkdir -p "$release_dir"
    
    # 复制文件
    cp "$BUILD_DIR/$PROJECT_NAME" "$release_dir/"
    cp "config.toml" "$release_dir/"
    cp "README.md" "$release_dir/"
    cp -r "docs" "$release_dir/" 2>/dev/null || true
    
    # 创建压缩包
    local archive_name="${PROJECT_NAME}-${VERSION}-$(uname -s)-$(uname -m).tar.gz"
    cd "$BUILD_DIR"
    tar -czf "$archive_name" -C release .
    cd ..
    
    print_success "发布包已创建: $BUILD_DIR/$archive_name"
}

# 显示项目状态
show_status() {
    print_info "项目状态:"
    echo "  项目名称: $PROJECT_NAME"
    echo "  版本: $VERSION"
    echo "  源码目录: $SRC_DIR"
    echo "  构建目录: $BUILD_DIR"
    
    if [ -f "$BUILD_DIR/$PROJECT_NAME" ]; then
        local size=$(du -h "$BUILD_DIR/$PROJECT_NAME" | cut -f1)
        local mtime=$(stat -c %y "$BUILD_DIR/$PROJECT_NAME" 2>/dev/null || stat -f %Sm "$BUILD_DIR/$PROJECT_NAME")
        echo "  可执行文件: $BUILD_DIR/$PROJECT_NAME ($size)"
        echo "  构建时间: $mtime"
    else
        echo "  可执行文件: 未构建"
    fi
}

# 主函数
main() {
    # 检查仓颉环境
    check_cangjie
    
    # 解析命令行参数
    case "${1:-help}" in
        "build")
            build_project
            ;;
        "build-opt")
            build_project_optimized
            ;;
        "build-min")
            build_project_minimal
            ;;
        "test")
            run_tests
            ;;
        "clean")
            clean_build
            ;;
        "install")
            install_deps
            ;;
        "run")
            shift
            run_server "$@"
            ;;
        "example")
            run_example
            ;;
        "benchmark")
            run_benchmark
            ;;
        "format")
            format_code
            ;;
        "lint")
            lint_code
            ;;
        "package")
            package_release
            ;;
        "status")
            show_status
            ;;
        "help"|"--help"|"-h")
            show_help
            ;;
        *)
            print_error "未知命令: $1"
            echo ""
            show_help
            exit 1
            ;;
    esac
}

# 运行主函数
main "$@"
